package com.haha.redission.bloomFilter;

import com.haha.redis.RedisKeyEnum;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class BloomFilterService {


    // 从配置文件中注入参数，提供默认值
    @Value("${bloom.filter.expected-insertions:100}")
    private long expectedInsertions; // 预期插入数量，默认100万
    @Value("${bloom.filter.false-probability:0.03}")
    private double falseProbability; // 误判率，默认3%


    private final RedissonClient redissonClient;
    private RBloomFilter<String> bloomFilter;

    public BloomFilterService(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }

    /**
     * 初始化布隆过滤器
     */
    @PostConstruct
    public synchronized void initBloomFilter() {
        if (bloomFilter == null) {
            // 从 Redisson 客户端获取一个指定名称的 RBloomFilter对象引用，为后续的初始化、添加元素和查询操作做准备
            String bloomFilterName = RedisKeyEnum.getKey(RedisKeyEnum.USER_REGISTER_BLOOM_FILTER_1);
            bloomFilter = redissonClient.getBloomFilter(bloomFilterName);
            // 判断布隆过滤器是否已存在，避免重复初始化
            if (!bloomFilter.isExists()) {
                // 初始化布隆过滤器
                bloomFilter.tryInit(expectedInsertions, falseProbability);
                log.info("布隆过滤器初始化完成，名字: {}，预期插入量: {}，误判率: {}", bloomFilterName,expectedInsertions, falseProbability);
            } else {
                log.info("布隆过滤器已存在，直接使用现有实例。");
            }
        }
    }

    /**
     * 添加元素到布隆过滤器
     */
    public void add(String key) {
        if (key == null) {
            log.warn("尝试向布隆过滤器添加空键");
            return;
        }
        bloomFilter.add(key);
        log.debug("已添加键到布隆过滤器: {}", key);
    }

    /**
     * 检查元素是否可能存在于布隆过滤器
     * @return true-可能存在；false-一定不存在
     */
    public boolean contains(String key) {
        if (key == null) {
            log.warn("尝试检查布隆过滤器中的空键");
            return false;
        }
        boolean result = bloomFilter.contains(key);
        log.debug("检查键 '{}' 是否存在: {}", key, result);
        return result;
    }

    /**
     * 重新初始化布隆过滤器（清空数据，慎用）
     */
    public synchronized void reinitialize() {
        if (bloomFilter != null) {
            bloomFilter.delete();
            bloomFilter.tryInit(expectedInsertions, falseProbability);
            log.info("布隆过滤器已重新初始化");
        }
    }
}